package cn.tedu.core;

import cn.tedu.http.EmptyRequestException;
import cn.tedu.http.HttpRequest;
import cn.tedu.http.HttpResponse;

import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * Author：程Sir
 * Name： SmallServer
 * Content:
 *  负责与指定客户端进行HTTP交互
 *     该线程将来与客户端交互的过程必须遵守HTTP协议要求，采取一问一答的方式进行,固定的解析步骤：
 *     1. 解析请求【问】
 *     2. 处理请求
 *     3. 响应请求【答】
 *
 *
 *
 */
public class RequestHandler implements Runnable {
    // 声明全局变量socket [socket中包含了所有客户端的请求信息]
    private Socket socket;
    public RequestHandler(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {

        try {
            // 1.请求解析
            HttpRequest httpRequest = new HttpRequest(socket);
            HttpResponse httpResponse = new HttpResponse(socket);

            // 2. 处理请求
            // 首先通过 httpRequest 获取请求中的抽象路径
            String url = httpRequest.getUrl();

        /*
            ./webapps/ 可以认为是一个固定的资源请求服务器，需要某个应用的资源文件，就可以在此服务器下面查找
            要求客户端输入请求资源时，一并要输入应用的名称例如：
                应用是找：myweb
                资源是找：index.html
                客户端发送的请求就应是： http://localhost:8080/myweb/index.html
         */
            File  file = new File("./webapps/"+url);

            // 若该资源存在且是一个文件，则正常做出响应
            // 3.做出响应
            if(file.exists() && file.isFile()){
                System.out.println("资源是存在的，下面进行反馈...");
                // 创建一个可以根据后缀名找mime类型的集合

  /*
                        html          text/html
                        css           text/css
                        js            application/javascript
                        png           image/png
                        gif           image/gif
                        jpg           image/jpg
                 */
                Map<String,String> mimeMapping = new HashMap<>();
                mimeMapping.put("html","text/html");
                mimeMapping.put("css","text/css");
                mimeMapping.put("js","application/javascript");
                mimeMapping.put("png"," image/png");
                mimeMapping.put("gif","image/gif");
                mimeMapping.put("jpg","image/jpg");

                // 1.现获取文件的名称
                String name = file.getName();
                // 2.通过名称获取后缀
                String type = name.substring(name.lastIndexOf(".")+1); // html
                // 3.通过拿到的后缀名找对应的mime类型
                String text = mimeMapping.get(type);

                // 给响应头设置指定的类型【至此，Headers集合中就已经有值了，只就是需要响应给客户端的】
                httpResponse.putHaeders("Content-Type",text);
                httpResponse.putHaeders("Content-Length",file.length()+"");

                // 当前存在的资源需要发送给响应对象
                httpResponse.setFileEntity(file);
                // 响应对象做具体的响应操作
                httpResponse.flush();

                System.out.println("数据响应完毕！");

            }else { // 如果资源不存在或者访问的是一个目录，则反馈404页面
                System.out.println("资源不存在，做404页面输出....");
                file = new File("./webapps/commons/404.html");
                // 访问资源不存在时，发送固定的404页面资源，依旧需要传送给响应对象
                httpResponse.setStatusCode(404); //告知浏览器，当前请求资源是不存在的！
                httpResponse.setStatuseReason("Not Found!"); // 解释和说明的内容
                // 给响应头设置指定的类型【至此，Headers集合中就已经有值了，只就是需要响应给客户端的】
                httpResponse.putHaeders("Content-Type","text/html");
                httpResponse.putHaeders("Content-Length",file.length()+"");

                httpResponse.setFileEntity(file);
                // 响应对象做具体的响应操作
                httpResponse.flush();

                System.out.println("404数据页面响应完毕！");


            }
        } catch (EmptyRequestException e) {
            System.err.println(e.getMessage()); // 控制台信息输出的时候显示的是红色，但是不会按逻辑输出
        } finally {
            try {
                // 一次请求，对应一次响应，响应结束，socket关闭，达到释放资源的目的
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


}
